package org.voidness.squaretilesframework.loaders;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import org.voidness.oje2d.GLImage;
import org.voidness.oje2d.Utils;
import org.voidness.squaretilesframework.Map;
import org.voidness.squaretilesframework.MapObject;
import org.voidness.squaretilesframework.ObjectTileSet;
import org.voidness.squaretilesframework.Tile;
import org.voidness.squaretilesframework.TileSet;

/**
 * A loader for an old map format Loads maps in the format: mapName width (in
 * tiles) height (int tiles) 0 0 pathToImage 0 1 pathToImage ...
 * 
 */
public class SimpleLoader implements LoaderInterface {
    /**
     * This method loads a map in an old format.
     * 
     * @param mFilename The filename of the map to load
     * @param mTileSize The tile size used in the map
     * @return The newly loaded map
     */
    public Map load(String mFilename, int mTileSize) {
        try {
            // Open a buffer to the file contents
            BufferedReader dataFile =
                    new BufferedReader(new FileReader(mFilename));

            // Read the map name
            String mapName = dataFile.readLine();

            // Read the map's width and height (in tiles)
            int mapWidth = Integer.parseInt(dataFile.readLine().trim());
            int mapHeight = Integer.parseInt(dataFile.readLine().trim());

            // Start reading the tiles
            Map map = new Map(mapWidth, mapHeight);
            TileSet tileSet = new TileSet();
            ObjectTileSet objectTileSet = new ObjectTileSet();
            Tile tiles[][] = new Tile[mapWidth][mapHeight];
            tiles = initializeTiles(map, mapWidth, mapHeight);
            String line = null;
            String[] tileValues = null;
            while ((line = dataFile.readLine()) != null) {
                // Split the line using spaces
                tileValues = line.split(" ");

                // Get the tile's information
                int x = Integer.parseInt(tileValues[0].trim());
                int y = Integer.parseInt(tileValues[1].trim());
                String fileName = tileValues[2].trim();
                boolean walkable =
                        Integer.parseInt(tileValues[3].trim()) == 0 ? true
                                : false;
                String objectName = tileValues[4].trim();

                int imageIndex = -1;
                if (!fileName.equalsIgnoreCase("null")) {
                    // Search the tileSet for this image name
                    imageIndex = tileSet.find(fileName);
                    if (imageIndex < 0) {
                        // System.out.println("Loading: " +
                        // tileValues[2].trim());
                        tileSet.addImage(new GLImage(tileValues[2].trim(),
                                mTileSize, mTileSize, false));
                        // System.out.println("adding: " + tileValues[2].trim()
                        // + " to the tileset");
                        imageIndex = tileSet.size() - 1;
                    }
                }

                int objectIndex = -1;
                if (!objectName.equalsIgnoreCase("null")) {
                    // Search the object set for this object image name
                    if (objectName != null) {
                        objectIndex = objectTileSet.find(objectName);
                        if (objectIndex < 0) {
                            objectTileSet.addObject(new MapObject(objectName));
                            objectIndex = objectTileSet.size() - 1;
                        }
                    }
                }

                // Create the new tile
                tiles[x][y] = new Tile(imageIndex, objectIndex, map, walkable);
            }

            // Define the values
            map.setName(mapName);
            map.setTiles(tiles);
            map.setTileSet(tileSet);
            map.setObjectTileSet(objectTileSet);

            // Return the new map
            return map;
        } catch (FileNotFoundException e) {
            Utils.dump("Map file not found: " + mFilename, Utils.ERROR);
            System.exit(1);
        } catch (IOException e) {
            Utils.dump("Error reading map file: " + mFilename, Utils.ERROR);
            System.exit(1);
        }

        // If we got here, some wicked stuff happened
        Utils.dump("Strange error reading map file: " + mFilename, Utils.ERROR);
        System.exit(1);
        return null;
    }

    /**
     * Initializes the temporary tiles
     * 
     * @param mMap The reference map to set in the tiles
     * @param mWidth The width of the map
     * @param mHeight The height of the map
     * @return The newly generated tile array
     */
    private Tile[][] initializeTiles(Map mMap, int mWidth, int mHeight) {
        Tile[][] tiles = new Tile[mWidth][mHeight];
        for (int i = 0; i < mWidth; i++)
            for (int j = 0; j < mHeight; j++)
                tiles[i][j] = new Tile(-1, -1, mMap, true);
        return tiles;
    }
}